package base.list;

import base.CObject;
import base.function.CFunction;
import base.value.CStringValue;
import base.value.CValue;
import base.value.userobject.CUserObject;
import java.util.LinkedList;

public class CElement extends CFunction {
	public CStringValue ReturnedStringValue = new CStringValue( "" );
	
	
	
	@Override
	public void Init() {
		AssertParam( 2 );
	}
	
	
	
	@Override
	public CValue GetValue() {
		CValue Value = Param[ 0 ].GetValue();
		switch( Value.GetType() ) {
			case String:
				ReturnedStringValue.Value = ToString( Value );
				return ReturnedStringValue;
			case Array:
				return ToArrayValue( Value );
			case List:
				return ToListValue( Value );
			default:
				Error( "Параметр должен быть строкой, массивом или списком" );
				return null;
		}		
	}

	
	
	@Override
	public boolean ToBoolean() {
		CValue Value = Param[ 0 ].GetValue();
		switch( Value.GetType() ) {
			case String:
				return true;
			case Array:
				return ToArrayValue( Value ).ToBoolean();
			case List:
				return ToListValue( Value ).ToBoolean();
			default:
				Error( "Параметр должен быть строкой, массивом или списком" );
				return false;
		}		
	}

	
	
	@Override
	public int ToInt() {
		CValue Value = Param[ 0 ].GetValue();
		int Index = Param[ 1 ].ToInt() - 1;
		switch( Value.GetType() ) {
			case String:
				return Integer.parseInt( ToString( Value ) );
			case Array:
				return ToArrayValue( Value ).ToInt();
			case List:
				return ToListValue( Value ).ToInt();
			default:
				Error( "Параметр должен быть строкой, массивом или списком" );
				return 0;
		}		
	}

	
	
	@Override
	public float ToFloat() {
		CValue Value = Param[ 0 ].GetValue();
		switch( Value.GetType() ) {
			case String:
				return Float.parseFloat( ToString( Value ) );
			case Array:
				return ToArrayValue( Value ).ToFloat();
			case List:
				return ToListValue( Value ).ToFloat();
			default:
				Error( "Параметр должен быть строкой, массивом или списком" );
				return 0;
		}		
	}
	
	
	
	@Override
	public String ToString(){
		CValue Value = Param[ 0 ].GetValue();
		switch( Value.GetType() ) {
			case String:
				return ToString( Value );
			case Array:
				return ToArrayValue( Value ).ToString();
			case List:
				return ToListValue( Value ).ToString();
			default:
				Error( "Параметр должен быть строкой, массивом или списком" );
				return null;
		}		
	}

	
	
	@Override
	public CUserObject ToObject() {
		CValue Value = Param[ 0 ].GetValue();
		switch( Value.GetType() ) {
			case Array:
				return ToArrayValue( Value ).ToObject();
			case List:
				return ToListValue( Value ).ToObject();
			default:
				Error( "Параметр должен быть массивом или списком" );
				return null;
		}		
	}
	
	
	
	@Override
	public CValue[] ToArray() {
		CValue Value = Param[ 0 ].GetValue();
		switch( Value.GetType() ) {
			case Array:
				return ToArrayValue( Value ).ToArray();
			case List:
				return ToListValue( Value ).ToArray();
			default:
				Error( "Параметр должен быть массивом или списком" );
				return null;
		}		
	}
	
	

	@Override
	public LinkedList<CValue> ToList() {
		CValue Value = Param[ 0 ].GetValue();
		switch( Value.GetType() ) {
			case Array:
				return ToArrayValue( Value ).ToList();
			case List:
				return ToListValue( Value ).ToList();
			default:
				Error( "Параметр должен быть массивом или списком" );
				return null;
		}		
	}
	
	
	
	public String ToString( CValue Value ){
		int Index = Param[ 1 ].ToInt() - 1;
		String String = Value.ToString();
		if( Index < 0 || Index >= String.length() ) Error( "Индекс за пределами строки" );
		return String.substring( Index, Index + 1 );
	}

	
	
	public CValue ToArrayValue( CValue ArrayValue ) {
		int Index = Param[ 1 ].ToInt() - 1;
		CValue[] Values = ArrayValue.ToArray();
		if( Index < 0 || Index >= Values.length ) Error( "Индекс за пределами массива" );
		return Values[ Index ].Clone();
	}

	
	
	public CValue ToListValue( CValue ListValue ) {
		int Index = Param[ 1 ].ToInt() - 1;
		LinkedList<CValue> Values = ListValue.ToList();
		if( Index < 0 || Index >= Values.size() ) Error( "Индекс за пределами списка" );
		return Values.get( Index ).Clone();
	}

	
	
	@Override
	public void EquateTo( CObject Obj ) {
		CValue Value = Param[ 0 ].GetValue();
		int Index = Param[ 1 ].ToInt() - 1;
		switch( Value.GetType() ) {
			case String:
				String String = ToString( Value );
				ReturnedStringValue.Value = String.substring( 0, Index - 1 ) + Obj.ToString() + String.substring( Index );
				Value.EquateTo( ReturnedStringValue );
				break;
			case Array:
				CValue[] Array = Value.ToArray();
				Array[ Index ] = Obj.GetValue();
				break;
			case List:
				LinkedList<CValue> List = Value.ToList();
				List.set( Index, Obj.GetValue() );
				break;
			default:
				Error( "Параметр должен быть строкой, массивом или списком" );
				break;
		}
	}
}
